热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

都市渲染流程解析:首个执行的Pass_1与不同LightMode的选择顺序分析

本文由编程笔记#小编为大家整理,主要介绍了_第一个被执行的Pass_1_不同LightMode 被选择的顺序相关的知识,希望对你有一定的参考价值。 第5章 第一个被执行的Pass 5.1 不同Ligh
本文由编程笔记#小编为大家整理,主要介绍了_第一个被执行的Pass_1_不同LightMode 被选择的顺序相关的知识,希望对你有一定的参考价值。



第5章 第一个被执行的Pass
5.1 不同LightMode 被选择的顺序
5.1.1 渲染路径和Pass的LightMode标签



    Unity支持3种RenderingPath,分别是VertexLit, ForwardDeferred Lighting,为此又定义
了在Pass中使用的LightMode标签Vertex, ForwardBase, ForwardAdd, PrepassBase, PrepassFinal
等,分别表示当前Pass是为在哪一个RenderingPath下设计使用的。


5.1.2设计可以检测渲染路径的材质


    现在的问题就是,在Shader中存在多个适应不同渲染路径的Pass时,Unity会怎么做?是按
照某种次序全部渲染?还是只是挑选出其中一个最优的Pass在对应的渲染路径下渲染?


    首先是Deferred.shader,这是一个被设计为只会在Camera的RenderingPath为Deferred模式
下输出红色的Shader,其代码如下:


Shader "Tut/Lighting/FirstLight/Lab_1/Deferred"
Properties
_MainTex ("Base (RGB)", 2D) = "white"

SubShader
Tags "RenderType"="Opaque"
Blend One One
CGPROGRAM
#pragma surface surf MyDeferred
half4 LightingMyDeferred_PrePass (SurfaceOutput s, half4 light)
half4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;

struct Input
float2 uv_MainTex;
;
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o)
o.Albedo=float3(1,0,0);

ENDCG


再就是Deferred_Forward.shader,这是一个包含可以适应Deferred以及Forward渲染路径的材
质,其中适应Deferred的部分输出(1 ,0, 0, 1)的红色,而适应Forward的部分只会输出的(0,
1, 0,  1)绿色;两个部分都使用了Blend One One混合模式,也就是说如果两部分都执行的话,
应该会输出(1,  1,  0,  1)的黄色,反之则只会输出被执行的那一个的输出颜色,也就是红色或
者绿色。其代码如下:






Shader "Tut/Lighting/FirstLight/Lab_1/Deferred_Forward"
SubShader
Blend One One
//.1
pass
Tags "LightMode"="ForwardBase"
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct vertOut
float4 pos:SV_POSITION;
float4 color:COLOR;
;
vertOut vert(appdata_base v)

vertOut o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.color=float4(0,1,0,1);
return o;

float4 frag(vertOut i):COLOR

return i.color;

ENDCG
//end pass
//.2
CGPROGRAM
#pragma surface surf MyDeferred
half4 LightingMyDeferred_PrePass (SurfaceOutput s, half4 light)
half4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;

struct Input
float2 uv_MainTex;
;
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o)
o.Albedo=float3(1,0,0);

ENDCG


    然后是Deferred_Forward_Vertex.shader,这个Shader和上面的Deferred_Forward.shader类似,
不同的是添加了可以适应VertexLit渲染路径的Pass,会输出蓝色。也就是说,如果3个都执行,
则会输出白色(1,1,1,1),否则会输出红、绿、蓝3个颜色的一个或两个的组合。其代码如一下:


Shader "Tut/Lighting/FirstLight/Lab_1/Deferred_Forward_Vertex"
SubShader
Blend One One
//.1
pass
Tags "LightMode"="Vertex"
Blend One Zero
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct vertOut
float4 pos:SV_POSITION;
float4 color:COLOR;
;
vertOut vert(appdata_base v)

vertOut o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.color=float4(0,0,1,1);
return o;

float4 frag(vertOut i):COLOR

return i.color;

ENDCG
//end pass
//.2
pass
Tags "LightMode"="ForwardBase"
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct vertOut
float4 pos:SV_POSITION;
float4 color:COLOR;
;
vertOut vert(appdata_base v)

vertOut o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.color=float4(0,1,0,1);
return o;

float4 frag(vertOut i):COLOR

return i.color;

ENDCG
//end pass
//.3
CGPROGRAM
#pragma surface surf MyDeferred
half4 LightingMyDeferred_PrePass (SurfaceOutput s, half4 light)
half4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;

struct Input
float2 uv_MainTex;
;
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o)
o.Albedo=float3(1,0,0);

ENDCG


    最后还有Deferred_Vertex.shader,这是一个含有可以适应Deferred和VertexLit模式的材质。
和Deferred_Forward_Vertex.shader类似,只不过去掉了适应Forward渲染路径的部分。还有
Forwardes_Vertex.shader,这个Shader去掉了适应Deferred模式的部分,还有单独适应Forward渲
染路径的Forward.shader,以及单独适应VertexLit渲染路径的Vertex.shader。其具体实现都很简单,
但是所有针对Deferred渲染路径的Pass最终都会输出红色(1,  0,  0,  1),所有针对Forward渲
染路径的Pass最终都会输出绿色(0, 1, 1, 1),所有针对VertexLit渲染路径的Pass最终都会输
出蓝色(0,  0,  1,  1)。


5.1.3设计便于检测渲染路径的场景


    在具体的场景中布置丰富的光源,可以保证任何一个RenderingPath都可以得到想要的光照,
将场景的主相机背景色设置为黑色,背景就不会对材质的Blend One One操作造成任何影响,绿
色的控制面板上的一系列按钮可以帮我们切换灯光的类型,以及Camera的RenderingPath。现在
我们可以根据不同渲染路径下颜色的输出判断不同的渲染路径下哪些Pass被执行,哪些没有。编
译并执行此场景。


5.1.4 VertexLit渲染路径下Pass的执行

    首先切换Camera到VertexLit模式下,如图所示。可以看到只有含LightMode = Vertex的Pass会被执行,并输出蓝色,其他的都没有被执行。



5.1.5 Forward渲染路径下Pass的执行

    切换相机到Forward渲染路径,可以看到如图所示的结果。凡是包含了针对Forward渲染路径的Pass都会被执行,并输出相应的绿色。如果没有包含针对Forward渲染路径的Pass,但是包含了针对VertexLit渲染路径的Pass,则也会被执行,并输出相应的蓝色。但是如果有Forward渲染路径的Pass可执行,就不会执行VertexLit渲染路径的Pass。针对Deferred渲染路径的Pass不会被执行。



5.1.6  Deferred渲染路径下Pass的执行

    再切换相机到Deferred渲染路径下,可以看到如图所示的结果。所有材质,凡是包含了针对Deferred的Pass可执行,则执行Deferred的Pass,并输出红色,其他Pass不会被执行。如果不包含针对Deferred的Pass,而且材质包含了Forward的Pass,则执行针对Forward设计的Pass输出相应的绿色。如果材质既没有针对Deferred的Pass,也没有针对Forward的Pass,则会执行Vertex的Pass,并输出蓝色。



5.1.7不同渲染路径下的Pass执行规则总结


    我们可以总结出,Unity在Deferred渲染路径下,则会寻找可在Deferred渲染模式下的Pass
然后返回,并不会执行其他渲染路径下的Pass,但是如果找不到Deferred状态下的Pass,则会再寻找Forward模式下的Pass并执行,然后返回,如果Forward模式下的Pass依然没有找到,则会寻找VertexLit模式下的Pass并执行。在Forward渲染路径下,会优先寻找Forward模式下可渲染的Pass,如果找不到,才会寻找 VertexLit模式下可渲染的Pass。


      但是无论如何,Unity在一个时间只会执行一个渲染路径下的Pass,它并不会将全部可执行
Pass都渲染
推荐阅读
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 哈密顿回路问题旨在寻找一个简单回路,该回路包含图中的每个顶点。本文将介绍如何判断给定的路径是否构成哈密顿回路。 ... [详细]
  • C语言基础入门:7个经典小程序助你快速掌握编程技巧
    本文精选了7个经典的C语言小程序,旨在帮助初学者快速掌握编程基础。通过这些程序的实践,你将更深入地理解C语言的核心概念和语法结构。 ... [详细]
  • 本题探讨了在一个有向图中,如何根据特定规则将城市划分为若干个区域,使得每个区域内的城市之间能够相互到达,并且划分的区域数量最少。题目提供了时间限制和内存限制,要求在给定的城市和道路信息下,计算出最少需要划分的区域数量。 ... [详细]
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 异常要理解Java异常处理是如何工作的,需要掌握一下三种异常类型:检查性异常:最具代表性的检查性异常是用户错误或问题引起的异常ÿ ... [详细]
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 在进行QT交叉编译时,可能会遇到与目标架构不匹配的宏定义问题。例如,当为ARM或MIPS架构编译时,需要确保使用正确的宏(如QT_ARCH_ARM或QT_ARCH_MIPS),而不是默认的QT_ARCH_I386。本文将详细介绍如何正确配置编译环境以避免此类错误。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 对于许多初学者而言,遇到总线错误(bus error)或段错误(segmentation fault/core dump)是极其令人困扰的。本文详细探讨了这两种错误的成因、表现形式及解决方法,并提供了实用的调试技巧。 ... [详细]
  • 本文详细介绍了如何解压并安装MySQL集群压缩包,创建用户和组,初始化数据库,配置环境变量,并启动相关服务。此外,还提供了详细的命令行操作步骤和常见问题的解决方案。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
author-avatar
涩味122_508
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有